package org.migrantalks.service.impl;

import com.alibaba.fastjson.JSONObject;
import io.vertx.core.*;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.DecodeException;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.shareddata.LocalMap;
import io.vertx.core.shareddata.SharedData;
import io.vertx.ext.auth.PubSecKeyOptions;
import io.vertx.ext.auth.jwt.JWTAuth;
import io.vertx.ext.auth.jwt.JWTAuthOptions;
import io.vertx.ext.jdbc.JDBCClient;
import io.vertx.ext.sql.SQLConnection;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
import org.migrantalks.base.Result;
import org.migrantalks.entity.SysUser;
import org.migrantalks.service.IUserService;
import org.migrantalks.utils.JdbcUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class UserService implements IUserService {

    private Vertx vertx;
    private JDBCClient jdbcClient;

    public UserService() {

        this.vertx = Vertx.vertx();
        /*SharedData sharedData = this.vertx.sharedData();
        LocalMap<String, Object> localMap = sharedData.getLocalMap("mvertx");
        JsonObject envConfig = (JsonObject) localMap.get("envConfig");
        JsonObject dataSource = envConfig.getJsonObject("dataSource");*/

        this.jdbcClient = new JdbcUtils(vertx).getDbClient();
    }

    private Handler<AsyncResult<SQLConnection>> connHandler(Promise promise, Handler<SQLConnection> handler) {
        return conn -> {
            if (conn.succeeded()) {
                final SQLConnection connection = conn.result();
                handler.handle(connection);
            } else {
                promise.fail(conn.cause());
            }
        };
    }

    /**
     * 用户登录
     */
    public void login(HttpServerResponse response,
                      String userName,
                      String password) {

        try {

            String sql = "select * from claims_sys_user where user_name=?";

            Promise result = Promise.promise();
            jdbcClient.getConnection(connHandler(result, connection ->
                    connection.queryWithParams(sql, new JsonArray().add(userName), rs -> {

                        if (rs.failed()) {
                            result.fail(rs.cause());

                        } else {

                            List<JsonObject> userList = rs.result().getRows();
                            if (userList.size() < 1) {
                                response.end(Json.encodePrettily(Result.fail("用户不存在")));
                                return;
                            }

                            SysUser user = JSONObject.parseObject(userList.get(0).toString(), SysUser.class);
                            if (!password.equals(user.getPass())) {
                                response.end(Json.encodePrettily(Result.fail("密码不对")));
                                return;
                            }

                            JWTAuthOptions config = new JWTAuthOptions()
                                    .addPubSecKey(new PubSecKeyOptions()
                                            .setAlgorithm("HS256")
                                            .setBuffer("keyboard cat"));

                            JWTAuth provider = JWTAuth.create(vertx, config);
                            String token = provider.generateToken(new JsonObject());

                            Map<String, Object> ret = new HashMap<>();
                            user.setPass(null);
                            ret.put("user", user);
                            ret.put("token", token);

                            response.end(Json.encodePrettily(Result.success(ret)));
                        }

                        connection.close();
                    })
            ));

        } catch (DecodeException e) {

            response.end(Json.encodePrettily(Result.fail("")));
        }
    }


    public static void auth2(Vertx vertx, RoutingContext ctx) {

        HttpServerResponse response = ctx.response();
        response.putHeader("Content-Type", "application/json;charset=utf-8");

        String token = ctx.request().getParam("token");

        JWTAuthOptions config = new JWTAuthOptions()
                .addPubSecKey(new PubSecKeyOptions()
                        .setAlgorithm("HS256")
                        .setBuffer("keyboard cat"));

        JWTAuth provider = JWTAuth.create(vertx, config);

        provider.authenticate(new JsonObject().put("jwt", token), auth -> {
            if (auth.succeeded()) {
                System.out.println(auth.result());
                response.end("认证成功！");
            } else {
                response.end("token无效");
            }
        });

    }

    /**
     * 用户列表
     */
    public void getUserList(HttpServerResponse response) {

        Promise<List<SysUser>> result = Promise.promise();
        String sql = "select * from claims_sys_user limit 10";

        jdbcClient.getConnection(connHandler(result, connection -> {
            connection.query(sql, r -> {

                if (r.failed()) {
                    result.fail(r.cause());

                } else {

                    List<SysUser> userList = new ArrayList<>();
                    List<JsonObject> retList = r.result().getRows();
                    retList.forEach(item -> {

                        SysUser user = JSONObject.parseObject(item.toString(), SysUser.class);
                        user.setPass(null);
                        userList.add(user);
                    });

                    result.complete(userList);
                    response.end(Json.encodePrettily(Result.success(result.future().result())));
                }

                connection.close();
            });
        }));
    }

    /**
     * 用户详情
     */
    public void getUserById(HttpServerResponse response,
                            String userId) {


        Promise<SysUser> result = Promise.promise();
        String sql = "select * from claims_sys_user where id=?";

        jdbcClient.getConnection(connHandler(result, connection -> {
            connection.queryWithParams(sql, new JsonArray().add(userId), r -> {

                if (r.failed()) {
                    result.fail(r.cause());

                } else {

                    JsonObject ret = r.result().getRows().get(0);
                    SysUser user = JSONObject.parseObject(ret.toString(), SysUser.class);
                    user.setPass(null);

                    response.end(Json.encodePrettily(Result.success(user)));
                }

                connection.close();
            });
        }));
    }
}
